﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using ModelResourceManager.UserModel.Enums;

namespace ModelResourceManager.UserModel
{
    public class UserManager
    {
        public bool Add(UserDTO userDto)
        {
            try
            {
                using (var container = new ResourceManagerEFContainer())
                {
                    var user = ParseToUser(userDto);
                    container.Users.Add(user);
                    container.SaveChanges();
                }
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        public bool Update(Guid userId, UserDTO userDto)
        {
            var user = GetCurrentUser(userId);
            user.Login = userDto.Login;
            user.FirstName = userDto.FirstName;
            user.LastName = userDto.LastName;
            user.Email = userDto.Email;
            user.Skype = userDto.Skype;
            user.MessageTimeSpan = userDto.MessageTimeSpan;
            try
            {
                using (var container = new ResourceManagerEFContainer())
                {
                    if (container.Users.Any())
                    {
                        container.Entry(ParseToUser(user)).State = EntityState.Modified;
                        container.SaveChanges();
                    }
                }
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        public bool Delete(Guid id)
        {
            try
            {
                using (var container = new ResourceManagerEFContainer())
                {
                    UserDTO currentUser = this.GetCurrentUser(id);
                    if (currentUser == null)
                        return false;
                    container.Users.Remove(ParseToUser(currentUser));
                    container.SaveChanges();
                }
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        public UserStatus ManageStatus(Guid userId, bool showStatus = false, UserStatus status = UserStatus.Active)
        {
            UserDTO userDto = this.GetCurrentUser(userId);
            if (!showStatus)
            {
                try
                {
                    using (var container = new ResourceManagerEFContainer())
                    {
                        if (userDto == null)
                            return UserStatus.None;
                        userDto.Status = status.ToString();
                        this.Update(userId, userDto);
                    }
                }
                catch (Exception)
                {
                    throw new Exception("Error in ManageStatus");
                }
            }
            return status;
        }

        public Guid Login(string login, string password)
        {
            var allUsers = GetAll();
            if (allUsers == null)
                return Guid.Empty;
            var thisUser = allUsers.FirstOrDefault(user =>
                    user.Login.ToLower().Trim() == login.ToLower().Trim() &&
                    user.Password == password);
            if (thisUser == default(UserDTO))
                return Guid.Empty;
            thisUser.Online = true;
            this.Update(thisUser.UserId, thisUser);
            return thisUser.UserId;
        }

        public bool Logout(Guid id)
        {
            UserDTO user = this.GetCurrentUser(id);
            if (user == null)
                return false;
            user.Online = false;
            return this.Update(id, user);
        }

        public UserDTO GetCurrentUser(Guid id)
        {
            try
            {
                using (var container = new ResourceManagerEFContainer())
                {
                    var currentUser = container.Users.FirstOrDefault(user => user.UserId == id);
                    if (currentUser == default(User))
                        return null;
                    return ParseToUserDto(currentUser);
                }
            }
            catch (Exception)
            {
                return null;
            }
        }

        public List<UserDTO> GetAll(bool activeOnly = false)
        {
            try
            {
                using (var container = new ResourceManagerEFContainer())
                {
                    if (container.Users == null || !container.Users.Any())
                        return null;
                    var users = container.Users.ToList();
                    if (activeOnly)
                        return users.Where(currentUser => currentUser.Status == UserStatus.Active.ToString())
                            .Select(ParseToUserDto)
                            .ToList();
                    return users
                        .Select(ParseToUserDto)
                        .ToList();
                }
            }
            catch (Exception)
            {
                return null;
            }
        }

        public string GetUserRole(Guid id)
        {
            UserDTO user = GetCurrentUser(id);
            if (user == null)
                return string.Empty;
            return user.Role.ToString();
        }

        public bool CheckLoginExists(string login)
        {
            List<UserDTO> users = GetAll();
            if (users == null)
                return false;
            return users.Any(user =>
                user.Login.ToLower().Trim() == login.ToLower());
        }

        public string GetUserName(Guid id)
        {
            UserDTO user = GetCurrentUser(id);
            if (user == null)
                return string.Empty;
            return user.FirstName;
        }

        private UserDTO ParseToUserDto(User user)
        {
            return new UserDTO()
            {
                UserId = user.UserId,
                FirstName = user.FirstName,
                LastName = user.LastName,
                Login = user.Login,
                Password = user.Password,
                Skype = user.Skype,
                Email = user.Email,
                Online = user.Online,
                MessageTimeSpan = user.MessageTimeSpan,
                Role = user.Role,
                Status = user.Status
            };
        }

        private User ParseToUser(UserDTO user)
        {
            return new User()
            {
                UserId = user.UserId,
                FirstName = user.FirstName,
                LastName = user.LastName,
                Login = user.Login,
                Password = user.Password,
                Skype = user.Skype,
                Email = user.Email,
                Online = user.Online,
                MessageTimeSpan = user.MessageTimeSpan,
                Role = user.Role,
                Status = user.Status
            };
        }
    }
}
